package ynu.edu.controller;

import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import io.github.resilience4j.timelimiter.annotation.TimeLimiter;
import org.springframework.web.bind.annotation.*;
import ynu.edu.Feign.ProviderClient;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

@RestController
@RequestMapping("/feign")
public class FeignController {

    private final ProviderClient providerClient;

    public FeignController(ProviderClient providerClient) {
        this.providerClient = providerClient;
    }

    @CircuitBreaker(name = "instanceA", fallbackMethod = "getDownA")
    @GetMapping("/getA/{id}")
    public String feignGetA(@PathVariable("id") String id) {
        System.out.println("断路器A访问正常");
        return "断路器A:"+providerClient.getData(id);
    }

    @GetMapping("/getB/{id}")
    @CircuitBreaker(name = "instanceB", fallbackMethod = "getDownB")
    public CompletableFuture<String> feignGetB(@PathVariable("id") String id) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                // 50%概率延迟3秒（模拟慢调用）
                if (Math.random() < 0.5) {
                    Thread.sleep(3000);
                } else {
                    Thread.sleep(1000);
                }

                String data = providerClient.getData(id);

                System.out.println("断路器B访问正常");
                return "断路器B:" + data;
            } catch (InterruptedException | RuntimeException e) {
                throw new CompletionException(e);
            }
        });
    }

    public String getDownA(String id, Throwable e) {
        e.printStackTrace();
        String message = "当前服务器异常火爆，因此方法降级";
        System.out.println(message);
        return message;
    }

    public CompletableFuture<String> getDownB(String id, Throwable e) {
        e.printStackTrace();
        String message = "当前服务器异常火爆，因此方法降级";
        System.out.println(message);
        return CompletableFuture.completedFuture(message);
    }
    @Bulkhead(name = "instanceC", fallbackMethod = "bulkheadFallback")
    @GetMapping("/getC/{id}")
    public String feignGetC(@PathVariable("id") String id) {
        System.out.println("隔离器访问正常");
        return "隔离器:"+providerClient.getData(id);
    }

    public String bulkheadFallback(String id, Throwable e) {
        e.printStackTrace();
        String message = "触发隔离器降级：当前并发请求过多，请稍后重试";
        System.out.println(message);
        return message;
    }

    @RateLimiter(name = "instanceRateLimit", fallbackMethod = "rateLimiterFallback")
    @GetMapping("/getD/{id}")
    public String rateLimitGet(@PathVariable("id") String id) {
        System.out.println("限流正常访问");
        return "限流返回：" + providerClient.getData(id);
    }

    public String rateLimiterFallback(String id, Throwable e) {
        System.err.println("触发限流降级：访问过于频繁，请稍后重试");
        return "触发限流降级：访问过于频繁，请稍后重试";
    }

}
